local RSNG = RSNG
local AceOO = AceLibrary("AceOO-2.0")
local L = AceLibrary("Ace-Locale-2.2"):new("RSNG")
local C = RSNG.Classes

local FilterList = AceOO.Class(C.IFilter)

function FilterList.prototype:init()
	FilterList.super.prototype.init(self)
	self.list = {}
end

function FilterList.prototype:Filter(...)
	for _, filter in ipairs(self.list) do
		if not filter:Filter(...) then return end
	end
	return true
end

function FilterList.prototype:Serialize(type, data)
	if type == "save" then
		for _, filter in ipairs(self.list) do
			for name, class in pairs(RSNG.RegisteredFilters) do
				if filter.class == class then
					local s = {
						class = name,
						data = {}
					}
					if AceOO.inherits(class, C.ISerialize) then
						filter:Serialize("save", s.data)
					end
					data[#data + 1] = s
					break
				end
			end
		end
	elseif type == "load" then
		local l = {}
		for _, info in ipairs(data) do
			local class = info.class
			local filter = RSNG.RegisteredFilters[class]:new()
			if AceOO.inherits(class, C.ISerialize) then
				filter:Serialize("load", info.data)
			end
		end
		self.list = l
	end
end

function FilterList.prototype:GetOptionTable()
	local t = self.options
	if not t then
		t = {
			add = {
				name = L["Add Filter"],
				type = "group",
				order = 100,
				args = {},
			},
			remove = {
				name = L["Remove Filter"],
				type = "group",
				order = 200,
				args = {},
			},
			space = {
				type = "separator",
				order = 300,
			}
		}
		self.options = t
	end
	
	local a, i = t.add.args, 1
	for name, class in pairs(RSNG.RegisteredFilters) do
		a["filter"..i] = {
			name = name,
			desc = L["Add a new %s"]:format(name),
			type = "execute",
			func = function () self.list[#self.list+1] = class:new() end,
			order = 100 + i,
		}
		i = i + 1
	end
	a = t.remove.args
	for index, l in ipairs(self.list) do
		local name
		for n, class in pairs(RSNG.RegisteredFilters) do
			if l.class == class then
				name = n
				break
			end
		end
		assert(name)
		a["filter"..index] = {
			name = name.." "..index,
			desc = L["Remove filter %s"]:format(name),
			type = "execute",
			func = function () table.remove(self.list, index) end,
		}
		if AceOO.inherits(l.class, C.ISerializable) then
			local opts = {
				name = name.." "..index,
				desc = L["Options for filter %s"]:format(name),
				type = "group",
				order = 400+i,
			}
			opts.args = l:GetOptionTable()
			t["filter"..index] = opts
		end
	end
	
	return t
end

C.FilterList = FilterList
